/*
 * SAM4E_AFE_10_bit_1Msps.c
 *
 * Created: 11/18/2014 2:26:29 PM
 *  Author: jerome.semette
 */ 

#include "sam.h"

volatile uint16_t uAdc_result;
volatile uint32_t uInter_Adc_Result;

 void Configure_TC0 (void) {
	
	/*Enable TC0 Clock */
	PMC->PMC_PCER0 = (0x1 << TC0_IRQn) ;  // TC0 Peripheral ID = 21
		
	/* Configure the TC0 to count at 15MHz (120 MHz / 8) and generate TIOA signal on RA and RC compare event  */
	TC0->TC_CHANNEL[0].TC_CMR = (TC_CMR_TCCLKS_TIMER_CLOCK2  | TC_CMR_ACPC_SET | TC_CMR_WAVE | TC_CMR_ACPA_CLEAR | TC_CMR_WAVSEL_UP_RC);
		
	/*configure TIO output at 15MHz/15 = 1MHz  */
	TC0->TC_CHANNEL[0].TC_RA = (uint32_t)7;
	TC0->TC_CHANNEL[0].TC_RC = (uint32_t)15;
    
}

static void Configure_AFEC0(void)
{

	/*Enable AFEC0 Clock (Periph ID = 30) */
	PMC->PMC_PCER0 = (0x1 << AFEC0_IRQn);
	 
	/*Set AFEC frequency to 20 MHz (PRESCAL value = 2)  */
	AFEC0->AFEC_MR |=  (2 << AFEC_MR_PRESCAL_Pos);
	    
	/* Set AFEC0 Hardware trigger to TC0 TIOA output*/
    AFEC0->AFEC_MR |= AFEC_MR_TRGSEL_AFEC_TRIG1 ; 
	
	/* Set AFEC0 start-up to 0 periods of ADCCLK*/
	AFEC0->AFEC_MR |= AFEC_MR_STARTUP_SUT0 ;
	
	/* Set Track time to 1 ADCCLK(TRACKTIM + 1) x ADCCLK periods) */
	AFEC0->AFEC_MR |= (0x0 <<  AFEC_MR_TRACKTIM_Pos) ;
	
    /* Disable PDC for AFEC0 */
	AFEC0->AFEC_PTCR = AFEC_PTCR_RXTDIS;
    
	/* Set 10-bit resolution */
	AFEC0->AFEC_EMR |=AFEC_EMR_RES_LOW_RES;
	
	/* Perform dummy read in Channel 1 Data register   */
	AFEC0->AFEC_CSELR = 1;
	AFEC0->AFEC_CDR;
	
	/* Enable Data ready and General Overrun interrupt */ 
    AFEC0->AFEC_IER |= (AFEC_IER_GOVRE | AFEC_IER_DRDY ) ;
	
	/* Enable general AFEC0 interrupt (ID 30)*/ 
    NVIC_EnableIRQ( AFEC0_IRQn );
	
	/* Enable internal hardware Trig*/ 
    AFEC0->AFEC_MR |= AFEC_MR_TRGEN;
	
	/* Enable AFEC0 channel 0 input (AD0 <=> PA17 <=> Pin 3 on EXT3 connector of the I/O Xplained Pro) */
    AFEC0->AFEC_CHER = (uint16_t) (0x1 << 0);
	
}

/*
 * Handles interrupts coming from the ADC.
 */
void AFEC0_Handler( void )
{
    uint32_t isr ;
	
	/* Read Interrupt status register*/
    isr = AFEC0-> AFEC_ISR;
	
	if (isr & AFEC_ISR_DRDY)
    {
	  /* Store received data */
      uInter_Adc_Result = (AFEC0->AFEC_LCDR & AFEC_LCDR_LDATA_Msk);
	  
	  /* Toggle test I/O */
	  if (PIOA->PIO_ODSR & PIO_ODSR_P15)
		PIOA->PIO_CODR = PIO_CODR_P15;
	  else 
	    PIOA->PIO_SODR = PIO_SODR_P15;
	
	}
	
	/* Check if General Overrun interrupt appears */
    if (isr & AFEC_ISR_GOVRE)
    {
		/** Debug ** Put a breakpoint there to monitor General overrun */ 
		while(1);
    }
}

void Configure_GPIOs()
{
   /* Initialize pin for sample per second monitoring */
   PIOA->PIO_OER = PIO_OER_P15;
   PIOA->PIO_PUDR = PIO_PUDR_P15;
   
   /* Disable pull-up on AFEC0 channel 0 line */
   PIOA->PIO_SODR = PIO_SODR_P17;
}


/**
 * \brief Application entry point for DSP_FFT example.
 * \return Unused (ANSI-C compatibility).
 */
void main( void )
{

   // Initialize System ( Watchdog disable , PLL config : MCK @ 120MHz)
   SystemInit();
   
   // configure GPIOs
   Configure_GPIOs();
   
   // configure AFEC0 
   Configure_AFEC0(); 
   
   // configure Timer counter 0   
   Configure_TC0();
   
   // Start Timer counter 0
   TC0->TC_CHANNEL[0].TC_CCR = (TC_CCR_CLKEN | TC_CCR_SWTRG); 
 
    while(1);
}
